﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadConsole
{
    public class SemaphoreSlimDemo
    {
        static SemaphoreSlim _sem = new SemaphoreSlim(3); // Capacity of 3

        public static void Enter(object id)
        {
            Console.WriteLine(id + " wants to enter");
            _sem.Wait();
            // only three thread can be here at a time
            Console.WriteLine(id + " is in!");
            Thread.Sleep(1000 * (int)id);
            Console.WriteLine(id + " is leaving");
            _sem.Release();
        }
    }

    public class ReaderWriterLockSlimDemo
    {
        static ReaderWriterLockSlim _rw = new ReaderWriterLockSlim();
        static List<int> _items = new List<int>();
        static Random _rand = new Random();

        static int GetRandNum(int max)
        {
            lock (_rand) { 
                return _rand.Next(max);
            }
        }

        public static void Read()
        {
            while (true)
            {
                _rw.EnterReadLock();
                foreach (int i in _items)
                {
                    Thread.Sleep(10);
                }
                _rw.ExitReadLock();
            }
        }

        public static void Write(object threadID)
        {
            while (true)
            {
                Console.WriteLine(_rw.CurrentReadCount + " concurrent readers");
                int newNumber = GetRandNum(100);
                _rw.EnterUpgradeableReadLock();
                if (!_items.Contains(newNumber))
                {
                    _rw.EnterWriteLock();
                    _items.Add(newNumber);
                    _rw.ExitWriteLock();
                    Console.WriteLine("Thread " + threadID + " added " + newNumber);
                }
                _rw.ExitUpgradeableReadLock();               
                Thread.Sleep(100);
            }
        }
    }
}
